package com.inter.controller.order;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.inter.config.StringOutputConstant;
import com.inter.entity.agatewaytobeijing.querydevice.beijing.response.ResponseQueryDevice;
import com.inter.entity.common.OrderPaymentManager;
import com.inter.entity.interentity.order.request.RequestOrderPackage;
import com.inter.entity.interentity.order.request.RequestOrderPackageData;
import com.inter.entity.interentity.order.request.RequestOrderPackageTradeData;
import com.inter.entity.interentity.order.response.ResponseOrderPackage;
import com.inter.entity.interentity.order.response.ResponseOrderPackageData;
import com.inter.entity.interentity.order.response.ResponseOrderPackageTradeData;
import com.inter.entity.interentity.utils.UtilsInterfacesPackage;
import com.inter.service.OrderPaymentManagerService;
import com.inter.service.PartnerProductPackageService;
import com.inter.service.PartnerService;
import com.inter.service.SequenceService;
import com.inter.service.agatewaytobeijing.GatewayToBeijingService;
import com.inter.utils.MD5;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * Demo 订购下单 ：travis，译翼通，tcl都是使用的这个接口
 * <p>
 * 此接口用于支付之前来下单，只为拿到orderId回去支付
 *
 * @author lm
 * @date 2018/08/31
 */
@RestController
@Api(tags = "订购套餐")
@Slf4j
public class OrderPackageController {
    @Autowired
    private SequenceService sequenceService;
    @Autowired
    PartnerProductPackageService partnerProductPackageService;
    @Autowired
    OrderPaymentManagerService orderPaymentManagerService;
    @Autowired
    PartnerService partnerService;
    @Autowired
    GatewayToBeijingService toBeijingService;

    @CrossOrigin
    @PostMapping(value = "orderPackage", produces = "application/json;charset=utf-8")
    @ResponseBody
    @ApiOperation(value = "下单", response = ResponseOrderPackage.class)
    public String orderPackage(@ApiParam @RequestBody RequestOrderPackage requestOrderPackage) {
        // 1，生成流水号
        String connSeqNo = sequenceService.getPackageTaskNo();
        // 2,生成当前时间戳
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String curTime = df.format(new Date());
        //3,定义要回复的内容
        String jsonString;
        UtilsInterfacesPackage utils = new UtilsInterfacesPackage();
        if (StringUtils.isBlank(JSON.toJSONString(requestOrderPackage))) {
            log.info("请求报文不合法:requestStr为空");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }

        String requestStr = JSON.toJSONString(requestOrderPackage);
        log.info("【下单】请求：" + requestStr);
        RequestOrderPackage requestPackage = JSONArray.parseObject(requestStr, RequestOrderPackage.class);
        if (null == requestPackage.getSign()) {
            log.info("请求报文不合法:sign为空");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }
        String requestSign = requestPackage.getSign();
        if (null == requestPackage.getData()) {
            log.info("请求报文不合法:data为空");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }

        RequestOrderPackageData requestData = requestPackage.getData();
        if (StringUtils.isBlank(requestData.getPartnerCode()) || StringUtils.isBlank(requestData.getConnSeqNo()) || StringUtils.isBlank(requestData.getTradeTime()) ||
                StringUtils.isBlank(requestData.getToken()) || StringUtils.isBlank(requestData.getTradeType()) || StringUtils.isBlank(requestData.getLang()) || null == requestData.getTradeData()) {
            log.info("请求报文不合法:data参数不合法");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }

        String partnerCode = requestData.getPartnerCode();
        String partnerName = partnerProductPackageService.queryPartnerNameBypartnerCode(partnerCode);
        String secret = partnerService.findSecretByPartnerCode(partnerCode);
        log.info("渠道名称：" + partnerName + ";密钥是：" + secret);
        String connNo = requestData.getConnSeqNo();
        String tradeTime = requestData.getTradeTime();
        String token = requestData.getToken();
        String tradeType = requestData.getTradeType();
        String lang = requestData.getLang();
        RequestOrderPackageTradeData tradeData = requestData.getTradeData();

        // 将请求体json转成String
        String str = JSON.toJSONString(requestData);
        // 将Str拿去计算签名
        String sign = utils.calculateSignature(str);
        if (!requestSign.equalsIgnoreCase(sign)) {
            log.info("签名验证失败！");
            jsonString = utils.publicMessage(connNo, partnerCode, tradeTime, token, tradeType);
            return jsonString;
        }

        if (StringUtils.isBlank(partnerName) || StringUtils.isBlank(secret)) {
            log.info("请求报文不合法:data参数不合法");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }

        if (StringUtils.isBlank(tradeData.getDeviceId()) || StringUtils.isBlank(tradeData.getDeviceType()) || StringUtils.isBlank(tradeData.getPackageName()) || StringUtils.isBlank(tradeData.getPackageCode()) ||
                StringUtils.isBlank(tradeData.getPackageType()) || StringUtils.isBlank(tradeData.getRequestOrderId()) || StringUtils.isBlank(tradeData.getCurrencyCodeType()) || StringUtils.isBlank(tradeData.getOrderPeriod()) || StringUtils.isBlank(tradeData.getAmount())) {
            log.info("请求报文不合法:tradeData的值为null或者为空");
            jsonString = utils.dataWeiKong(connSeqNo, curTime);
            return jsonString;
        }

        String deviceId = tradeData.getDeviceId();
        String deviceType = tradeData.getDeviceType();
        String globalOrder = tradeData.getGlobalOrder();
        String packageCode = tradeData.getPackageCode();
        /*为了防止下单时上报的packageName是英文的，所以这边的packageName我们还是去数据库查出来比较好；*/
        String name = partnerProductPackageService.queryPackageNameByCode(packageCode, partnerCode);
        String packageType = tradeData.getPackageType();
        String requestOrderId = tradeData.getRequestOrderId();
        String currencyCodeType = tradeData.getCurrencyCodeType();
        String orderPeriod = tradeData.getOrderPeriod();
        String amount = tradeData.getAmount();

        //TCL方案兼容
        if (StringOutputConstant.CODE_P000591.equals(partnerCode)) {
            String amountObtainedCNY = partnerProductPackageService.querycnyByCode(partnerCode, packageCode);
            String amountObtainedUSD = partnerProductPackageService.queryusdByCode(partnerCode, packageCode);
            if (StringOutputConstant.CODE_CNY.equals(currencyCodeType)) {
                if (!amount.equalsIgnoreCase(amountObtainedCNY)) {
                    Float Period = Float.parseFloat(amount) / Float.parseFloat(amountObtainedCNY);
                    orderPeriod = new BigDecimal(Period).toString();
                }
            } else if (StringOutputConstant.CODE_USD.equals(currencyCodeType)) {

                if (!amount.equalsIgnoreCase(amountObtainedUSD)) {
                    Float Period = Float.parseFloat(amount) / Float.parseFloat(amountObtainedUSD);
                    orderPeriod = new BigDecimal(Period).toString();
                }

            }
        }
        log.info("接口上报的订购周期：" + orderPeriod + "；接口上报的金额" + amount + "最终的订购周期：" + orderPeriod);
        /*先存订单：先把拿到的数据存到数据库去.还是需要判断一下数据库里面是不是已经有这条请求下单的记录了*/
        Integer count = orderPaymentManagerService.findDataByRequestOrderId(requestOrderId, deviceId, orderPeriod, partnerCode, packageCode);
        if (count > 0) {
            /*数据库里面已经有记录了就说明不要去重复请求单号了，直接回复重复请求！走到这边说明重复请求相同的数据*/
            log.info("重复的请求！");
            jsonString = utils.duplicateRequestMessage(connNo, partnerCode, tradeTime, token, tradeType);
            return jsonString;
        }
        /*先去验证卡片的有效性，如果卡片无效就不允许下单*/
        ResponseQueryDevice device = toBeijingService.queryDevice(deviceId, partnerCode, secret);
        boolean b3 = null == device || null == device.getCode() || null == device.getData() || StringUtils.isBlank(device.getData().getLifecycle()) || "null".equalsIgnoreCase(device.getData().getLifecycle()) ||
                (StringUtils.isNotBlank(device.getData().getLifecycle()) && (device.getData().getLifecycle().equals(StringOutputConstant.CODE_FOUR) || device.getData().getLifecycle().equals(StringOutputConstant.CODE_FIVE)));
        if (b3) {
            log.info("【iccId验证】SIM卡已过期");
            jsonString = utils.invalidUnableOrder(connNo, partnerCode, token, curTime, tradeType);
            return jsonString;
        }

        /*先给第三方回复一个orderNo*/
        String orderNo = sequenceService.getOrderNoTaskNo();
        if (StringUtils.isBlank(orderNo)) {
            jsonString = utils.orderFailed(connNo, partnerCode, token, curTime, tradeType);
            return jsonString;
        }
        /*下单记录生成*/
        OrderPaymentManager userOrder = new OrderPaymentManager();
        userOrder.setPartnerCode(partnerCode);
        userOrder.setPartnerName(partnerName);
        userOrder.setPackageCode(packageCode);
        userOrder.setPackageName(name);
        userOrder.setDeviceId(deviceId);
        userOrder.setDeviceType(deviceType);
        userOrder.setPackageType(packageType);
        userOrder.setOrderPeriod(orderPeriod);
        userOrder.setAmount(amount);
        userOrder.setIsOpen("0");
        userOrder.setGlobalOrder(globalOrder);
        userOrder.setRequestOrderId(requestOrderId);
        userOrder.setOrderCurrency(currencyCodeType);
        userOrder.setOrderNo(orderNo);

        Integer co = orderPaymentManagerService.storageOrderPayment(userOrder);
        if (co > 0) {
            log.info("下单记录生成");
            //2,要准备回报的数据了
            List<ResponseOrderPackageTradeData> responseTradeData = new ArrayList<ResponseOrderPackageTradeData>();
            ResponseOrderPackageTradeData tra = new ResponseOrderPackageTradeData();
            tra.setOrderId(orderNo);
            tra.setOrderStartDate("");
            tra.setOrderExpireDate("");
            responseTradeData.add(tra);

            ResponseOrderPackageData data = new ResponseOrderPackageData();
            data.setConnSeqNo(connNo);
            data.setPartnerCode(partnerCode);
            data.setToken(token);
            data.setTradeTime(curTime);
            data.setTradeType(tradeType);
            data.setTradeRstCode(1000);
            data.setTradeRstMessage("success");
            data.setTradeData(responseTradeData);

            ResponseOrderPackage responseOrder = new ResponseOrderPackage();
            responseOrder.setData(data);
            responseOrder.setSign(MD5.calcMD5(JSON.toJSONString(data)));
            // 返回给调用者的报文
            jsonString = JSON.toJSONString(responseOrder);
            log.info("响应报文：" + jsonString);
            return jsonString;
        }
        log.info("下单记录生成失败");
        jsonString = utils.orderFailed(connNo, partnerCode, token, curTime, tradeType);
        return jsonString;
    }

}
